AWS SSOのIAM RoleからAssume RoleできるIAM Roleを作成する
AWS SSOを使う時、ユーザーは各アカウントにできたIAM RoleにAssume Roleすることで各アカウントで操作ができるようになります。
さて今回は、AWS SSOユーザーがAssume RoleするためのIAM Role、この特定のRoleからさらにAssume Roleできる別アカウントのIAM Roleを作成したいと思います。
以下は、このRoleの信頼ポリシー(=Assume Roleできるエンティティを定義するポリシー)をどのように設定するか、という話です。
ガバガバで設定する
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::(AccountAのID):root" }, "Action": "sts:AssumeRole" } ] }
上記のようにPrincipal句で(AccountID):root
と設定すると、そのアカウント内の全てのIAMエンティティからのAssume Roleが許可されます。AWS SSOのロールもその対象内ですのでAssume Roleが可能です。
が、今回許可したいのはAWS SSOの特定のロール一つだけです。他の全てエンティティにもAssume Roleを許可してしまうのはセキュリティリスクがあります。というわけで許可対象を絞る方法を以降の段で模索します。
失敗例: Principal句で絞る
まず最初に考えられる方法はPrincipal句の設定をもっと絞る方法です。ですが先にお伝えすると、この方法は今回はうまくいきませんでした。
詳細を説明します。前述の通り、AWS SSOの特定のロールのみをAssume Roleの対象としたいです。ですので、そのようなARNをPrincipal句に書けば良いです。RoleのARNは以下要素で構成されます。
arn:aws:iam::(AccountAのID):role/(パス(あれば))(ロール名)
SSOで作成されるロールには/aws-reserved/sso.amazonaws.com/(リージョンID)/
というパスが設定されます。なお、SSOを米国東部 (バージニア北部)=us-east-1で設定している場合は(リージョンID)/
は不要です。
ARNを固定できない
上記ARN構成要素のうち、今回の場合ロール名が固定できません。なぜかというとAWS SSOのアクセス権限セットの割り当てで作成されるIAM Roleの名前はAWSReservedSSO_(アクセス権限セット名)_(英字小文字と数字の組み合わせのランダムな文字列)
となります。例えばアクセス権限セットの名前がAdministratorAccess
なのであれば、作成されるIAM Roleの名前はAWSReservedSSO_AdministratorAccess_dcd926ba31da45ec
などになります。このランダムな文字列込みのARNを書いてしまえば良いのですが、今回はIaCで汎用的に対象のRoleを作成したかったので、アカウント毎に異なる値を記述するのは避けたかったです。
固定できないならワイルドカードを使えばいいじゃない
上記理由で今回の場合ARNを固定することができません。ではワイルドカードを使ってもう少し曖昧に指定すれば?と考えました。具体的にはPrincipal句に以下のように書くということです。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::(AccountAのID):role/aws-reserved/sso.amazonaws.com/ap-northeast-1/AWSReservedSSO_AdministratorAccess_*" }, "Action": "sts:AssumeRole" } ] }
ですがこれはエラーになります。どうやらPrincipal句でIAM RoleのARNの一部にワイルドカードを使うことはできないようです。
これはなぜかというと、Principal句でIAM RoleのARNを書くと、そのARNはポリシーを保存するときにロールの一意のプリンシパル ID に変換されるからです。故にワイルドカードのような曖昧な書き方はできず、かつ存在しないRoleのARNを書くこともできません。これはロール削除して再作成することにより、誰かがそのロールの特権をエスカレートするリスクを緩和することを目的としています。
この点(=Principal句でIAM RoleのARNの一部にワイルドカードを使うことはできない)について公式のソースを見つけることができませんでした。が、IAMユーザーについては以下に記載されているので、Roleに関してもそうだと判断しました。
成功例: Condition句で絞る
Principal句で絞り込むのは無理そうでしたので諦めます。代わりにCondition句での実現を試みました。aws:PrincipalArn
というグローバル条件コンテキストキーを発見したのでこちらを使うことで要件を実現できました。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::(AccountAのID):root" }, "Action": "sts:AssumeRole", "Condition": { "ArnLike": { "aws:PrincipalArn": "arn:aws:iam::(AccountAのID):role/aws-reserved/sso.amazonaws.com/ap-northeast-1/AWSReservedSSO_AdministratorAccess_*" } } } ] }
まとめ
AWS SSOのロールからのみAssume RoleできるIAM Roleの信頼ポリシーの書き方についてレポートしました。Principal句でIAM UserやIAM RoleのARNを指定する際にワイルドカードを使うことができないことがわかりました。ワイルドカードを使いたい場合は、Principal句は (AccountID):root
と広く設定した上で、Condition句でaws:PrincipalArn
を使うことで実現できることがわかりました。